//==============================================================================
//
//             DThread - the thread class in the ofc-library
//
//               Copyright (C) 2009  Dick van Oudheusden
//  
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free
// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
//==============================================================================
// 
//  $Date: 2008-07-20 14:03:51 $ $Revision: 1.11 $
//
//==============================================================================

#include "ofc/DThread.h"


#if _INTERFACE_

#include "ofc/config.h"

#if defined(HAVE_LIBPTHREAD)
#define HAVE_DTHREAD
#endif

#ifdef HAVE_DTHREAD

#define DTHR_INTERACTIVE             (OBJC_THREAD_INTERACTIVE_PRIORITY)
#define DTHR_BACKGROUND              (OBJC_THREAD_BACKGROUND_PRIORITY)
#define DTHR_LOW                     (OBJC_THREAD_LOW_PRIORITY)

//
// The Thread class implements methods for using a thread. It wraps around 
// Objective-Cs thread functions.
//
// @example
// XXX
// 

@interface DThread : DObject
{
@private
  id            _object;   // the object for the selector
  SEL           _selector; // the selector to be run
  objc_thread_t _thread;   // the thread
}
#endif

#endif


#ifdef HAVE_DTHREAD


@implementation DThread


//// Constructors

//
// Initialise a thread 
//
// @return the object
//

- (DThread *) init
{
  [self init :self :@selector(run)];

  return self;
}

//
// Initialise a thread with an object and selector
// 
// @param object   the object
// @param selector the selector
// 
// @return the object
// 

- (DThread *) init :(id) object :(SEL) selector
{
  [super init];
  
  _object   = object;
  _selector = selector;
  _thread   = NULL;
  
  return self;
}


//// Copy related methods

//
// Do a shallow copy of the object (not implemented)
//
// @return the object
//
- shallowCopy
{
  WARNING(DW_METHOD_NOT_IMPL, "shallowCopy");
  
  return [super shallowCopy];
}


//// Deconstructor

//
// Free the object
// 

- free
{
  [super free];
  
  return self;
}


//// Main methods

//
// Start the thread
//
// @param argument  the argument for the thread
//
// @return success
//

- (BOOL) start :(id) argument
{
  if (_thread != NULL)
  {
    WARNING(DW_INVALID_STATE, "start");
  }
  else
  {
    _thread = objc_thread_detach (_selector, _object, argument);
  }
  
  return (_thread != NULL);
}

//
// Main thread function (to be overridden)
//
// @param argument  the argument for the thread
//

- (void) run :(id) argument
{
}


//// Class methods

//
// Get the priority of the current thread
//
// @return the priority (DTHR_INTERACTIVE, DTHR_BACKGROUND, DTHR_LOW)
//

+ (int) priority
{
  return (objc_thread_get_priority());
}

//
// Set the priority of the current thread
//
// @param priority   the priority

// @return the object
//

+ (void) priority :(int) priority
{
  if ((priority < DTHR_INTERACTIVE) || (priority > DTHR_LOW))
  {
    WARNING(DW_INVALID_ARG, "priority");
  }
  else
  {
    objc_thread_set_priority(priority);
  }
}

//
// Yield the current thread
// 
//

+ (void) yield
{
  objc_thread_yield();
}

//
// Exit the current thread
// 
// @return the result
// 

+ (int) exit
{
  return (objc_thread_exit());
}

@end
#endif

/*===========================================================================*/

